home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14918 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.6 KB  |  157 lines

  1. Path: rain.fr!world-net!usenet
  2. From: Frederic LACHASSE <lachass@worldnet.fr>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Urgent help - pointers to functions
  5. Date: Tue, 02 Apr 1996 19:37:33 +0000
  6. Organization: World-Net information exchange, Internet provider.
  7. Message-ID: <VA.00000075.0004d66b@fred>
  8. References: <internews46B6FAA4E6@argonet.co.uk>
  9. Reply-To: lachass@worldnet.fr
  10. NNTP-Posting-Host: pm6-122.sct.fr
  11. X-Newsreader: Virtual Access by Ashmount Research Ltd, http://www.ashmount.com
  12.  
  13. In article <internews46B6FAA4E6@argonet.co.uk>, Charlotte Tomlinson 
  14. <eeyore@argonet.co.uk> wrote:
  15. > I have implemented a template doubly linked list, the backbones of which
  16. > is as follows:
  17. [snip]
  18. > Then I have a class, called fuzzyset, which uses this dll as a container
  19. > for fuzzyel instances:
  20. > //fuzzyset.h
  21. > /*snip*/
  22. > class fuzzyset {
  23. >         private:
  24. >         dllist<fuzzyel> members;
  25. >         public:
  26. >         fuzzyset() {}
  27. >         fuzzyset(const fuzzyset&);
  28. >         fuzzyset(const fuzzyel&);
  29. > /*other functions and operators*/
  30. > };
  31. > What I would like to do is, within dllist, to implement a function forEach
  32. > that take a pointer to a function as one argument, and somehow the rest of
  33. > the arguments required by that function, and carries that function out
  34. > over each element of the list. 
  35. > One example of what I need to do is as follows.  In my main program (where
  36. > fuzzyset is included), I need to be able to call a function that prints
  37. > every element of the 'members' list in any called instance of a fuzzyset.
  38. > I need the forEach function to be quite generic, because I will have other
  39. > uses for it later.
  40.  
  41. The most generic way of providing a callback function is using a pointer to a  
  42. base class with a virtual member function:
  43.  
  44. template <class T>
  45. class CallbackFor
  46. {
  47. public:
  48.   virtual void operator()(T const&) = 0;
  49.   virtual ~CallbackFor() {}
  50. };
  51.  
  52. usage will be:
  53.  
  54. void fuzzyset::applyForEach(CallbackFor<fuzzyel>* cb)
  55. {
  56.   for (...)
  57.   {
  58.     (*cb)(elem);
  59.   }
  60.   
  61.   delete cb;
  62. }
  63.  
  64. Then you can do anything you like. The most common derivations are:
  65. - calling functions with preliminary fixed parameters: (example use 2 fixed 
  66. parms but is easy to extend to any number)
  67.  
  68. template <class T, class T1, class T2>
  69. class CallbackFn2 : public CallbackFor<T>
  70. {
  71. public:
  72.   typedef void (*pfn)(T1, T2, T const&);
  73. private:
  74.   pfn fn;
  75.   T1 arg1;
  76.   T2 arg2;
  77. public:
  78.   CallbackFn2(pfn f, T1 a1, T2 a2)
  79.   : fn(f), arg1(a1), arg2(a2) {}
  80.   void operator()(T const&);
  81. };
  82.  
  83. template <class T, class T1, class T2>
  84. void CallbackFn2<T,T1,T2>::operator()(T const& arg)
  85. {
  86.   fn(arg1, arg2, arg);
  87. }
  88.  
  89. template <class T, class T1, class T2>
  90. CallbackFor<T>* callback(CallbackFn2<T,T1,T2>::pfn fn, T1 arg1, T2 arg2)
  91. {
  92.   return new CallbackFn2<T,T1,T2>(fn, arg1, arg2);
  93. }
  94.  
  95. - calling a non-static member function of a class
  96. template <class T, class TT>
  97. class CallbackMember : public CallbackFor<T>
  98. {
  99. public:
  100.   typedef void (TT::*pfn)(T const&);
  101. private:
  102.   pfn fn;
  103.   TT* obj;
  104. public:
  105.   CallbackMember(pfn f, TT* o)
  106.   : fn(f), obj(o) {}
  107.   void operator()(T const&);
  108. };
  109.  
  110. template <class T, class TT>
  111. void CallbackMember<T,TT>::operator()(T const& arg)
  112. {
  113.   obj->*fn(arg);
  114. }
  115.  
  116. template <class T, class TT>
  117. CallbackFor<T>* callback(CallbackMember<T,TT>::pfn fn, TT* obj)
  118. {
  119.   return new CallbackMember<T,TT>(fn, obj);
  120. }
  121.  
  122.  
  123. Usage are:
  124.  
  125. void doFn(int, char*, fuzzyel const&);
  126. class doMbr
  127. {
  128. public:
  129.   do(fuzzyel const&);
  130. };
  131.  
  132.  fuzzyset set;
  133.  doMbr action;
  134.  set.applyForEach(callback(doFn, 1, "coucou"));
  135.  set.applyForEach(callback(&doMbr::do, &action));
  136.  
  137. Except for typo, this should work.
  138.  
  139. I hope this'll help.
  140.  
  141.  Frederic LACHASSE (ECP 86)
  142.  CompuServe: 100530,2005
  143.  Internet: lachass@worldnet.fr
  144.  
  145.